﻿namespace CommonFramework.Event
{
    public static class Delegate
    {
        public delegate void Action();
        public delegate void Event(object param);
        public delegate T Func<T>();

        public delegate void Param0();
        public delegate void Param1<in T>(T param);
        public delegate void Param2<in T, in T1>(T param, T1 param1);
        public delegate void Param3<in T, in T1, in T2>(T param, T1 param1, T2 param2);

        public delegate Ret_T Return<out Ret_T>();
        public delegate Ret_T Param1WithRet<in T, out Ret_T>(T param);
        public delegate Ret_T Param2WithRet<in T, in T1, out Ret_T>(T param, T1 param1);
        public delegate Ret_T Param3WithRet<in T, in T1, in T2, out Ret_T>(T param, T1 param1, T2 param2);

        public static bool ContainsCallback<Registor_T, Callback_T>(Registor_T registor, Callback_T callback)
            where Registor_T : System.Delegate
            where Callback_T : System.Delegate
        {
            if (registor == null || callback == null)
                return false;
            var invocations = registor.GetInvocationList();
            foreach (var invocate in invocations)
            {
                if (invocate == callback)
                    return true;
            }
            return false;
        }
        public static void AddCallbackIfNotExist<Registor_T, Callback_T>(ref Registor_T registor, Callback_T callback)
            where Registor_T : System.Delegate
            where Callback_T : System.Delegate
        {
            if (callback == null)
                return;
            if (registor == null)
                registor = (Registor_T)(object)callback;
            else
            {
                if (!ContainsCallback(registor, callback))
                    registor = (Registor_T)System.Delegate.Combine(registor, callback);
            }
        }
        public static void RemoveCallback<Registor_T, Callback_T>(ref Registor_T registor, Callback_T callback)
            where Registor_T : System.Delegate
            where Callback_T : System.Delegate
        {
            if (callback == null || registor == null)
                return;
            registor = (Registor_T)System.Delegate.Remove(registor, callback);
        }
    }
}